package dal

import (
	"context"

	commonTools "algo-sdk-go/common/tools"
	"algo-sdk-go/framework/middleware/db/mongodb/dbops"
	"algo-sdk-go/project/matchmaking/adapter/convertor"
	"algo-sdk-go/project/matchmaking/adapter/po"
	"algo-sdk-go/project/matchmaking/common/constant"
	"algo-sdk-go/project/matchmaking/domain/models/entity"
	"algo-sdk-go/project/matchmaking/matchMaking-api/config"

	"github.com/pkg/errors"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type RecommendUserDal struct {
	recommendUserCollection *mongo.Collection
}

func NewRecommendUserRepository(config *config.Config) *RecommendUserDal {
	mc, err := mongo.Connect(context.Background(), options.Client().ApplyURI(config.Mongo.Url))
	if err != nil {
		panic(err)
	}

	return &RecommendUserDal{
		recommendUserCollection: mc.Database(config.Mongo.DataBase).Collection(constant.RecommendUserDBName),
	}
}

func (r *RecommendUserDal) Save(ctx context.Context, recommendUser *entity.RecommendUser) error {
	timeNew := commonTools.TimeNowStr()
	_, err := r.recommendUserCollection.InsertOne(ctx, &po.RecommendUser{
		Id:                  recommendUser.Id,
		RecommendUserIdList: recommendUser.RecommendUserIdList,
		RecommendDate:       recommendUser.RecommendDate,
		Status:              "",
		IsDeleted:           false,
		CreateUser:          "",
		CreateTime:          timeNew,
		ModifyUser:          "",
		UpdateTime:          timeNew,
	})
	return err
}

func (r *RecommendUserDal) Modify(ctx context.Context, recommendUser *entity.RecommendUser) error {
	if err := dbops.Valid(dbops.ValuesNotAllowEmpty(recommendUser.RecommendUserIdList, "推荐用户列表为空")); err != nil {
		return errors.WithMessage(err, "RecommendUserDal_valid_error")
	}

	filter := dbops.GetFilter(
		dbops.WithStringValue(constant.DBId, recommendUser.Id),
	).AndOperator()

	updateInfo := dbops.GetUpdater(
		dbops.SetValue(constant.DBRecommendUserIdList, recommendUser.RecommendUserIdList),
		dbops.SetValue(constant.DBRecommendDate, recommendUser.RecommendDate),
	).Set()

	if _, err := r.recommendUserCollection.UpdateOne(ctx, filter, updateInfo); err != nil {
		return errors.Wrapf(err, "RecommendUserDal Modify UpdateOne error, recommendUser: %+v", commonTools.JsonToString(recommendUser))
	}
	return nil
}

func (r *RecommendUserDal) LoadNearestRecommendUser(ctx context.Context) (entity.RecommendUser, error) {
	var (
		recommendUser = entity.RecommendUser{}
	)
	filter := LoadNearestRecommendUserFilter()

	opts := dbops.GetOpts(
		dbops.SetSortBy([]dbops.SortBy{
			{
				SortKey: constant.DBUpdateTime,
				SortWay: -1,
			},
		}, constant.DBUpdateTime),
		dbops.SetPageNumPageSize(1, 6, false),
	).Get()

	result, err := dbops.GetAllItemsFromMongo(ctx, r.recommendUserCollection, filter, opts, convertor.ConvertRecommendUserEntity)
	if err != nil {
		return recommendUser, err
	}
	if len(result) == 0 {
		return recommendUser, nil
	}
	return result[0], nil

}
